/*================================================================
*   Copyright (C) 2024 baichao All rights reserved.
*
*   文件名称：thread_cancel.c
*   创 建 者：baichao
*   创建日期：2024年03月21日
*   描    述：
*
================================================================*/

/*
 * nanosleep是取消点，如果线程执行到此处时被其他线程取消，就会出现以下情况：互斥量还没有解锁，但持有锁的线程已不复存在。
 * 这种情况下其他线程再也无法申请到互斥量，很有可能在某处就会陷入死锁的境地。
 */

#include <pthread.h>
#include <stdio.h>

void* cancel_unsafe(void* arg) {
  static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  pthread_mutex_lock(&mutex);  // 此处不是撤消点
  struct timespec ts = {3, 0};
  nanosleep(&ts, 0);             // 是撤消点
  pthread_mutex_unlock(&mutex);  // 此处不是撤消点
  return 0;
}

int main(void) {
  pthread_t t;
  pthread_create(&t, 0, cancel_unsafe, 0);
  pthread_cancel(t);
  pthread_join(t, 0);
  cancel_unsafe(0);  // 再次调用，发生死锁！
  return 0;
}
